package com.iteaj.plugin.event;

import com.alipay.sofa.ark.common.util.ClassLoaderUtils;
import com.alipay.sofa.ark.spi.event.biz.BeforeBizStartupEvent;
import com.alipay.sofa.ark.spi.model.Biz;
import com.alipay.sofa.ark.spi.service.event.EventHandler;
import com.iteaj.plugin.IzoneConfig;
import com.iteaj.plugin.spi.Consts;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * create time: 2020/2/27
 *
 * @author iteaj
 * @since 1.0
 */
public class BeforeBizStartEventHandle implements EventHandler<BeforeBizStartupEvent> {

    private static URL[] COMMON_URLS = new URL[]{};
    static {
        File parentFile = IzoneConfig.getRootDir();
        if(parentFile != null) {
            // 加载lib类库
            File libDir = new File(parentFile, Consts.LIB_DIR);
            if(libDir.exists() && libDir.isDirectory()) {
                File[] files = libDir.listFiles(pathname -> pathname.getPath().endsWith(".jar"));
                if(files != null) {
                    COMMON_URLS = Arrays.stream(files).map(libFile->{
                        try {
                            return libFile.toURI().toURL();
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                            return null;
                        }
                    }).toArray(URL[] :: new);
                }
            }
        }
    }

    @Override
    public void handleEvent(BeforeBizStartupEvent event) {
        Biz bizModel = event.getSource();
        URL[] oriClassPath = bizModel.getClassPath();
        if(COMMON_URLS.length > 0) {
            List<URL> list = new ArrayList<>();
            Arrays.asList(oriClassPath).forEach(item->{
                list.add(item);
            });
            Arrays.asList(COMMON_URLS).forEach(item->list.add(item));

            URL[] urls = list.stream().toArray(URL[]::new);
            Class<? extends Biz> bizModelClass = bizModel.getClass();
            Class<? extends ClassLoader> aClass = bizModel.getBizClassLoader().getClass();
            try {
                Method loader = bizModelClass.getDeclaredMethod("setClassLoader", ClassLoader.class);

                // 使用新的类加器加载 application 主类
                ClassLoader classLoader = aClass.getConstructor(String.class, URL[].class).newInstance(bizModel.getIdentity(), urls);
                ClassLoaderUtils.pushContextClassLoader(classLoader);

                // 重新设置BizModel的类加载器
                loader.invoke(bizModel, classLoader);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public int getPriority() {
        return HIGHEST_PRECEDENCE;
    }
}
